
package panels;

import core.COINCOMOComponent;
import core.COINCOMOSubComponent;
import core.COINCOMOSubSystem;
import core.COINCOMOSystem;
import core.COINCOMOUnit;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Insets;
import java.text.DecimalFormat;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import main.GlobalMethods;

/**
 *
 * @author Raed Shomali
 */
public class SystemOverviewPanel extends JPanel implements HyperlinkListener
{
    JTextPane summaryReportTextPane = new JTextPane();

    JScrollPane summaryScroller = new JScrollPane( summaryReportTextPane );

    public static COINCOMOSystem currentSystem = null;

    COINCOMOSubSystem currentSubSystem = null;

    COINCOMOComponent currentComponent = null;

    DecimalFormat format1Decimal = new DecimalFormat( "0.0" );
    DecimalFormat format2Decimals = new DecimalFormat( "0.00" );

    public SystemOverviewPanel( COINCOMOUnit unit )
    {
        // Text Pane
        TitledBorder dictionaryTitleBorder = BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder( EtchedBorder.RAISED ) , "Summary Report" );
        dictionaryTitleBorder.setTitleColor( Color.BLUE );
        dictionaryTitleBorder.setTitlePosition( TitledBorder.BELOW_TOP );
        dictionaryTitleBorder.setTitleJustification( TitledBorder.CENTER );
        summaryReportTextPane.setEditable( false );
        summaryScroller.setBorder( dictionaryTitleBorder );
        summaryReportTextPane.setContentType( "text/html" );
        summaryReportTextPane.setMargin( new Insets( 20 , 20 , 20 , 20 ) );

        summaryReportTextPane.addHyperlinkListener( this );

        updateReport( unit );

        // GUI
        this.setLayout( new BorderLayout() );

        this.add( summaryScroller );
        this.add( new JLabel( "    " ) , BorderLayout.NORTH );
        this.add( new JLabel( "    " ) , BorderLayout.SOUTH );
        this.add( new JLabel( "    " ) , BorderLayout.EAST );
        this.add( new JLabel( "    " ) , BorderLayout.WEST );
    }

    public void updateReport( COINCOMOUnit unit )
    {
        // For Efficient Appending ...
        StringBuilder output = new StringBuilder();

        if ( unit instanceof COINCOMOSystem )
        {
            output.append( "<h2> System " + unit.getName() + "\'s Overview: </h2>" );

            this.currentSystem = (COINCOMOSystem) unit;
            this.currentSubSystem = null;
            this.currentComponent = null;
        }
        else if ( unit instanceof COINCOMOSubSystem )
        {
            output.append( "<h2> Sub System " + unit.getName() + "\'s Overview: </h2>" );

            this.currentSubSystem = (COINCOMOSubSystem) unit;
            this.currentComponent = null;
        }
        else
        {
            output.append( "<h2> Component " + unit.getName() + "\'s Overview: </h2>" );

            this.currentComponent = (COINCOMOComponent) unit;
        }

        // To color each row differently
        String color = "";
                
        // If there are sub units ...
        if ( !unit.getListOfSubUnits().isEmpty() )
        {
            color = "DDDDDD";

            output.append( "<table border = '1' cellpadding = '1'  cellspacing = '1' width = '100%' align = 'center'>" );
            output.append( "<tr>" );
            output.append( "<th bgcolor = " + color + "> Name </th>" );
            output.append( "<th bgcolor = " + color + "> Size KSLOC </th>" );
            output.append( "<th bgcolor = " + color + "> Effort </th>" );
            if( unit instanceof COINCOMOComponent ){}
            else
            {
            output.append( "<th bgcolor = " + color + "> Schedule </th>" );
            }
            output.append( "<th bgcolor = " + color + "> Cost </th>" );
            
            if( unit instanceof COINCOMOComponent )
            {
            output.append( "<th bgcolor = " + color + "> Staff </th>" );
            }
            output.append( "</tr>" );
        }
        else
        {
            output.append( "There are currently no " + ((unit instanceof COINCOMOSystem) ? "Sub systems " : "Components ") + "in " + unit.getName() + "<br />" );
        }

        // Get all subunits
        Vector<COINCOMOUnit> orderedVector = GlobalMethods.getOrderedVector( unit.getListOfSubUnits() );

        // Used for determining an Odd Row from an Even one
        int rowIndex = 0;

        long totalSLOC = 0 ;
        float totalCost = 0 ;
        float totalStaff = 0 ;
        
        // Go Through subunits
        for( int c = 0 ; c < orderedVector.size() ; c ++ )
        {
            COINCOMOUnit tempUnit = (COINCOMOUnit) orderedVector.get( c ) ;

            // Determine Row being even or odd
            if ( rowIndex++ % 2 == 0 )
            {
                color = "CCFFFF";
            }
            else
            {
                color = "white";
            }

            output.append( "<tr align = 'center'>" );
            
            // If a Sub Component ... No Drilling More Down ...
            if( tempUnit instanceof COINCOMOSubComponent )
            {
                output.append( "<td bgcolor = " + color + ">" + tempUnit.getName() + "</td>" );                
            }
            else
            {
                output.append( "<td bgcolor = " + color + ">" + "<a href = 'http://" + tempUnit.getUnitID() + "' >" + tempUnit.getName() + "</a>" + "</td>" );
            }
            
            totalSLOC += tempUnit.getFinalSLOC() ;
            totalCost += tempUnit.getCost() ;
            totalStaff += tempUnit.getStaff() ; 
            
            output.append( "<td bgcolor = " + color + ">" + tempUnit.getFinalSLOC() + "</td>" );
            if( tempUnit instanceof COINCOMOSubComponent)
            {
                COINCOMOSubComponent subcomponent = (COINCOMOSubComponent) tempUnit;
                float effort = subcomponent.getEstEffort();
                output.append( "<td bgcolor = " + color + ">" + format2Decimals.format(effort) + "</td>" );
//                output.append( "<td bgcolor = " + color + ">" + "Schedule" + "</td>" );
            }
            else if( tempUnit instanceof COINCOMOComponent )
            {
                COINCOMOComponent component = (COINCOMOComponent)tempUnit;
                output.append( "<td bgcolor = " + color + ">" + format2Decimals.format(component.getTotalEffort()) + "</td>" );
                output.append( "<td bgcolor = " + color + ">" + format2Decimals.format(component.getTotalSchedule()) + "</td>" );
            }
            else
            {
                output.append( "<td bgcolor = " + color + ">" + format2Decimals.format(tempUnit.getTotalEffort()) + "</td>");
                output.append( "<td bgcolor = " + color + ">" + format2Decimals.format(tempUnit.getTotalSchedule()) + "</td>" );
            }
            output.append( "<td bgcolor = " + color + "> $" + format2Decimals.format( GlobalMethods.roundOff( tempUnit.getCost() , 2 ) )  + "</td>" );
            
            
            if( unit instanceof COINCOMOComponent )
            {
            output.append( "<td bgcolor = " + color + ">" + format1Decimal.format( GlobalMethods.roundOff( tempUnit.getStaff() , 1 ) ) + "</td>" );
            }
            output.append( "</tr>" );

            // No More Records ?
            if ( c == orderedVector.size() - 1 )
            {
                color = "CCFF66";

                output.append( "<tr align = 'center'>" );
                output.append( "<th bgcolor = " + color + ">" + "Total" + "</th>" );
                output.append( "<th bgcolor = " + color + ">" + totalSLOC + "</th>" );
                output.append( "<th bgcolor = " + color + ">" + format2Decimals.format(unit.getTotalEffort()) + "</th>" ); 
                if(unit instanceof COINCOMOSubSystem || unit instanceof COINCOMOSystem)
                {
                    output.append( "<th bgcolor = " + color + ">" + format2Decimals.format(unit.getTotalSchedule()) + "</th>" );
                }                
                output.append( "<th bgcolor = " + color + "> $" + format2Decimals.format( GlobalMethods.roundOff( totalCost , 2 ) ) + "</th>" );
                
                if( unit instanceof COINCOMOComponent )
                {
                output.append( "<th bgcolor = " + color + ">" + "--" + "</th>" );
                }
                output.append( "</tr>" );
            }
        }

        output.append( "</table>" );

        // If Not the System Page ...
        if( !( unit instanceof COINCOMOSystem ) )
        {
            // Print "Back" Link ...
            output.append( "<br /> &nbsp; <a href = 'https://" + unit.getParentID() + "' >" + "Go Back" + "</a>" );
        }
        
        summaryReportTextPane.setText( output.toString() );
    }

    public void hyperlinkUpdate( HyperlinkEvent e )
    {
        // User Clicked The Link
        if ( e.getEventType() == HyperlinkEvent.EventType.ACTIVATED )
        {
            /*
             * To Differentiate between a back Button and a show details one 
             * I used 'https' for "Go Back" and 'http' for More Details
             */
            
            // If Back ??
            if( e.getURL().toString().startsWith( "https://" ) )
            {
                // If On the Component Page ...
                if ( this.currentComponent != null )
                {
                    // Go Back to Sub System Page ..
                    updateReport( currentSubSystem );
                }
                else
                {
                    // Go Back To System Page ..
                    updateReport( currentSystem );
                }
            }
            else
            {
                if ( this.currentComponent != null )
                {
                    // Go To Sub Component Page ...
                    updateReport( currentComponent.getListOfSubUnits().get( Long.parseLong( e.getURL().toString().replaceAll( "http://" , "" ) ) ) );
                }
                else if ( this.currentSubSystem != null )
                {
                    // Go To Component Page ...
                    updateReport( currentSubSystem.getListOfSubUnits().get( Long.parseLong( e.getURL().toString().replaceAll( "http://" , "" ) ) ) );
                }
                else
                {
                    // Go to Sub System Page
                    updateReport( currentSystem.getListOfSubUnits().get( Long.parseLong( e.getURL().toString().replaceAll( "http://" , "" ) ) ) );
                }
            }
        }
    }

}
